package cc.telecomdigital.tdstock.trading.Services;

import java.util.ArrayList;
import java.util.List;

import org.ksoap2.serialization.SoapObject;
import org.ksoap2.serialization.SoapSerializationEnvelope;

import cc.telecomdigital.tdstock.R;
import cc.telecomdigital.tdstock.Framework.UniqueItem.DeviceInfo;
import cc.telecomdigital.tdstock.Framework.UniqueItem.TDStockLog;
import cc.telecomdigital.tdstock.Services.SoapTransport;

import cc.telecomdigital.tdstock.trading.Common.Trade_AppConstant;
import cc.telecomdigital.tdstock.trading.Common.Trade_StockHistItem;
import cc.telecomdigital.tdstock.trading.Common.Trade_StockHistRecord;
import cc.telecomdigital.tdstock.trading.Common.Trade_SymbolTranslation;

import android.content.Context;
import android.os.Handler;
import android.os.Message;
public class TradeGetMultipleOrder
{
	private final String	LOG_TAG	= "TradeGetMultipleOrder";

	// Call back interface
	public interface ITradeGetMultipleOrderResponse
	{
		/** if iSuccessfulSend == false, it means the there is a communication error
		    do not consider the iReponse as valid response **/
		void ResponseFunc(boolean iSuccessfulSend,
				TradeGetMultipleOrderResult iResponse);
	}

	public class TradeGetMultipleOrderResult
	{
		public boolean				Result;
		public String				StatusCode;
		public String				BrokerMessage;
		public Trade_StockHistRecord	historyItems;

		public TradeGetMultipleOrderResult(boolean iResult,
				String iStatusCode, String iBrokerMessage,
				Trade_StockHistRecord iHistoryItem)
		{
			Result = iResult;
			StatusCode = iStatusCode;
			BrokerMessage = iBrokerMessage;
			if (iHistoryItem != null)
				historyItems = new Trade_StockHistRecord(iHistoryItem);
			else
				historyItems = null;
		}
	}

	private final boolean debugMode = false;
	private SoapObject					soapRequest;
	private Context					callerContext;
	private boolean					demoData	= false;
	private Handler					messageHandler;
	private ITradeGetMultipleOrderResponse	responseHandler;

	/** Requesting for a Trade Order Modification
	 * @param iContext - Owner
	 * @param iName - Server required userName
	 * @param iPassword - Server required password
	**/		
	public TradeGetMultipleOrder(Context iContext, String iName, String iPassword)
	{
		callerContext = iContext;

		soapRequest = new SoapObject(TradeAppInfo.NAMESPACE, "MultipleOrder");
		soapRequest.addProperty("DeviceID",
				TradeAppInfo.GetDeviceID(iContext));
		soapRequest.addProperty("UIN", TradeAppInfo.GetUIN());
		soapRequest.addProperty("ProtocolVer",
				TradeAppInfo.GetProtocolVersion());
		soapRequest.addProperty("BrokerID", TradeAppInfo.BrokerID);
		soapRequest.addProperty("Language", DeviceInfo.GetLanguageString());
		soapRequest.addProperty("ClientID", iName);
		
		soapRequest.addProperty("ClientPassword", iPassword);		
	}

	/** Requesting for a Trade Order Modification
	 * @param iContext - Owner
	 * @param iName - Server required userName
	**/		
	public TradeGetMultipleOrder(Context iContext, String iName)
	{
		callerContext = iContext;

		soapRequest = new SoapObject(TradeAppInfo.NAMESPACE, "MultipleOrder");
		soapRequest.addProperty("DeviceID",
				TradeAppInfo.GetDeviceID(iContext));
		soapRequest.addProperty("UIN", TradeAppInfo.GetUIN());
		soapRequest.addProperty("ProtocolVer",
				TradeAppInfo.GetProtocolVersion());
		soapRequest.addProperty("BrokerID", TradeAppInfo.BrokerID);
		soapRequest.addProperty("Language", DeviceInfo.GetLanguageString());
		soapRequest.addProperty("ClientID", iName);		
	}

	public void Dispose()
	{		
		messageHandler = null;
		if (debugMode)
			TDStockLog.i(LOG_TAG, "We have no reference anymore");	
	}
	
	/** If we are running a demo version, the iUseDemoData could be a fake send **/
	public void SendRequest(boolean iUseDemoData, ITradeGetMultipleOrderResponse iTradeGetMultipleOrderResponse)
	{
		demoData = iUseDemoData;
		responseHandler = iTradeGetMultipleOrderResponse;
		messageHandler = new Handler()
		{
			@Override
			public void handleMessage(Message msg)
			{
				if (responseHandler == null)
					return;

				switch (msg.what)
				{
					case REQUEST_DATA_SENT_FAIL:
						responseHandler.ResponseFunc(false, null);
						break;

					case REQUEST_DATA_SENT_SUCCESS:
						responseHandler.ResponseFunc(true,
								(TradeGetMultipleOrderResult) msg.obj);
						break;
				}
			}
		};
		// Start the Thread
		Thread internalThreadObj = new Thread()
		{
			@Override
			public void run()
			{
				Message msg;
				TradeGetMultipleOrderResult infoData;

				// Provide success or fail reply
				msg = new Message();
				infoData = SendData(demoData);
				if ((infoData.Result == false) || (infoData.StatusCode == null)
						|| (infoData.StatusCode.length() == 0))
					msg.what = REQUEST_DATA_SENT_FAIL;
				else
				{
					msg.what = REQUEST_DATA_SENT_SUCCESS;
					msg.obj = infoData;
				}
				messageHandler.sendMessage(msg);
			}			
		};		
		internalThreadObj.setName(LOG_TAG);
		internalThreadObj.start();
	}

	private final int	REQUEST_DATA_SENT_FAIL		= 0;
	private final int	REQUEST_DATA_SENT_SUCCESS	= 1;

	// Demo Data
	private Trade_StockHistRecord GetDemoRecord()
	{
		List<Trade_StockHistItem> historyList;
		Trade_StockHistItem historyItem;
		Trade_StockHistRecord recordItem;

		TDStockLog.d(LOG_TAG, "Using Prepared Data");
		historyList = new ArrayList<Trade_StockHistItem>();

		historyItem = new Trade_StockHistItem("00122", "鱷魚恤", "CROCODILE",
				"0.73", "HKD");
		historyItem.SetReqOrderInfo("11119", "0.610", "E",
				Trade_SymbolTranslation.TRANSACTIONTYPE_BID, "8,000", "電話",
				"2010-10-19 15:51:29");
		historyItem.SetProcessOrderInfo(
				Trade_SymbolTranslation.TRANSSTATUS_QUEUEING, "排隊中", "0",
				"0", "8000");
		historyList.add(historyItem);

		historyItem = new Trade_StockHistItem("00066", "港鐵公司", "MTR CORP.",
				"28.65", "HKD");
		historyItem.SetReqOrderInfo("11118", "30.6", "E",
				Trade_SymbolTranslation.TRANSACTIONTYPE_ASK, "3000", "手機",
				"2010-10-19 15:25:07");
		historyItem.SetProcessOrderInfo(
				Trade_SymbolTranslation.TRANSSTATUS_REJECTED, "已拒絕",
				"2500", "0", "500");
		historyItem.AppendProcessDetail("15:25:08  $30.60  2,500");
		historyList.add(historyItem);

		historyItem = new Trade_StockHistItem("00003", "中華煤氣",
				"HK & CHINA GAS", "19.00", "HKD");
		historyItem.SetReqOrderInfo("11117", "19.20", "E",
				Trade_SymbolTranslation.TRANSACTIONTYPE_BID, "6,000", "手機",
				"2010-10-19 15:07:15");
		historyItem.SetProcessOrderInfo(
				Trade_SymbolTranslation.TRANSSTATUS_CANCELED, "已取消",
				"5000", "1000", "0");
		historyItem.AppendProcessDetail("15:07:15  $19.20  5000");
		historyList.add(historyItem);


		historyItem = new Trade_StockHistItem("00086", "新鴻基", "SUN HUNG KAI",
				"6.640", "HKD");
		historyItem.SetReqOrderInfo("11116", "5.620", "E",
				Trade_SymbolTranslation.TRANSACTIONTYPE_BID, "28,000",
				"電話", "2010-10-19 14:42:28");
		historyItem.SetProcessOrderInfo(
				Trade_SymbolTranslation.TRANSSTATUS_PROCESSING, "交易中",
				"18000", "0", "10000");
		historyItem.AppendProcessDetail("14:42:28  $5.610  18,000");
		historyList.add(historyItem);

		historyItem = new Trade_StockHistItem("03988", "中行", "BANK OF CHINA",
				"4.370", "HKD");
		historyItem.SetReqOrderInfo("11115", "4.440", "E",
				Trade_SymbolTranslation.TRANSACTIONTYPE_ASK, "10000", "網上",
				"2010-10-18 14:31:02");
		historyItem.SetProcessOrderInfo(
				Trade_SymbolTranslation.TRANSSTATUS_QUEUEING, "排隊中", "0",
				"0", "10000");
		historyList.add(historyItem);

		historyItem = new Trade_StockHistItem("00941", "中移動", "CHINA MOBILE",
				"72.60", "HKD");
		historyItem.SetReqOrderInfo("11114", "82.55", "E",
				Trade_SymbolTranslation.TRANSACTIONTYPE_BID, "500", "手機",
				"2010-10-18 12:28:59");
		historyItem.SetProcessOrderInfo(
				Trade_SymbolTranslation.TRANSSTATUS_RECEIVED, "已收到", "500",
				"0", "0");
		historyItem.AppendProcessDetail("12:28:59  $82.55  500");
		historyList.add(historyItem);

		historyItem = new Trade_StockHistItem("02888", "渣打集團", "STANCHART",
				"207.80", "HKD");
		historyItem.SetReqOrderInfo("11113", "233.0", "E",
				Trade_SymbolTranslation.TRANSACTIONTYPE_ASK, "200", "網上",
				"2010-10-18 11:23:39");
		historyItem.SetProcessOrderInfo(
				Trade_SymbolTranslation.TRANSSTATUS_RECEIVED, "已收到", "200",
				"0", "0");
		historyItem.AppendProcessDetail("11:23:39  $233.0  200");
		historyList.add(historyItem);

		historyItem = new Trade_StockHistItem("00005", "匯豐控股",
				"HSBC HOLDINGS", "82.9", "HKD");
		historyItem.SetReqOrderInfo("11112", "82.55", "E",
				Trade_SymbolTranslation.TRANSACTIONTYPE_ASK, "3200", "手機",
				"2010-10-15 10:30:45");
		historyItem.SetProcessOrderInfo(
				Trade_SymbolTranslation.TRANSSTATUS_PROCESSING, "交易中",
				"1200", "0", "2000");
		historyItem.AppendProcessDetail("10:30:45  $82.55  1,200");
		historyList.add(historyItem);

		historyItem = new Trade_StockHistItem("00973", "L'OCCITANE",
				"L'OCCITANE", "18.24", "HKD");
		historyItem.SetReqOrderInfo("11111", "18.44", "E",
				Trade_SymbolTranslation.TRANSACTIONTYPE_ASK, "5713840000",
				"手機", "2010-10-15 10:05:00");
		historyItem.SetProcessOrderInfo(
				Trade_SymbolTranslation.TRANSSTATUS_PROCESSING, "交易中",
				"30000", "0", "5713810000");
		historyItem.AppendProcessDetail("10:05:00  $18.25  20,000");
		historyItem.AppendProcessDetail("10:04:29  $18.25  10,000");
		historyList.add(historyItem);

		recordItem = new Trade_StockHistRecord();
		recordItem.SetStockHistoryRecordList(historyList);

		return recordItem;
	}
	
	private TradeGetMultipleOrderResult SendData(boolean iDemoData)
	{
		//Prevent multiple call for object
		synchronized(TradeAppInfo.padLock)
		{
			boolean hasSent;
			SoapSerializationEnvelope envelope;
			TradeGetMultipleOrderResult resultCode;
			Trade_StockHistRecord portRecord;
	
			portRecord = null;
			resultCode = null;
			if (iDemoData == true)
			{
				try
				{
					Thread.sleep(Trade_AppConstant.demoHoldTime);
				}
				catch (InterruptedException e)
				{
					e.printStackTrace();
					TDStockLog.e(LOG_TAG, "SendData=>Exception: " + e.toString());
				}				
				resultCode = new TradeGetMultipleOrderResult(true, "0", null,
						GetDemoRecord());
				return resultCode;
			}
	
			hasSent = false;
			if (DeviceInfo.IsNetworkAvailable(callerContext) == false)
			{
				resultCode = new TradeGetMultipleOrderResult(hasSent, null, null,
						null);
				return resultCode;
			}
	
			envelope = new SoapSerializationEnvelope(TradeAppInfo.SOAP_VERSION);
	
			// Set packet ID
			soapRequest.addProperty("SeqNo", TradeAppInfo.GetSeqNo(true));
			// Last modification of the time
			soapRequest.addProperty(
					"Timestamp",
					TradeAppInfo.GetCurrentTimeStamp() + ","
							+ TradeAppInfo.GetSessionToken());
			envelope.setOutputSoapObject(soapRequest);
	
			String accountCode;
			String statusCode;
			String brokerMessage;
	
			List<Trade_StockHistItem> stockList;
	
			accountCode = null;
			statusCode = null;
			brokerMessage = null;
	
			stockList = null;
	
			try
			{
				SoapObject resultsRequestSOAP;
				SoapObject soapResults;
				SoapObject tradeGroup;
	
				SoapTransport dataTransfer;
				
				if (TradeAppInfo.useSSLSetting)
					dataTransfer = new SoapTransport(callerContext, TradeAppInfo.GetURLAddress(true),
												TradeAppInfo.SOAP_COMMUNIC_Timeout, R.raw.ca_stock);
				else
					dataTransfer = new SoapTransport(callerContext, TradeAppInfo.GetURLAddress(false), 
											   TradeAppInfo.SOAP_COMMUNIC_Timeout);
				if (debugMode)
					TDStockLog.i(LOG_TAG, "Try sending Data");	
				
				dataTransfer.SendData(TradeAppInfo.SOAP_SERVICENAME, envelope);
				
				resultsRequestSOAP = (SoapObject) envelope.bodyIn;
				if (debugMode)
					TDStockLog.i(LOG_TAG, "Parsing Data");			
				
				hasSent = true;			
				soapResults = (SoapObject) resultsRequestSOAP
						.getProperty("MultipleOrderResult");
	
				// If the reference number is not the one we create
				statusCode = TradeAppInfo.GetSoapProperty(soapResults, LOG_TAG,
						"StatusCode");
				if (statusCode.equals("0") == false)
					brokerMessage = TradeAppInfo.GetSoapProperty(soapResults,
							LOG_TAG, "Message");
				else
				{
					//accountCode = TradeAppInfo.GetSoapProperty(soapResults,
					//		LOG_TAG, "AccountCode");
					try
					{					
						tradeGroup = (SoapObject) soapResults
								.getProperty("trades");
						if ((tradeGroup != null) && (!tradeGroup.toString().equals("anyType{}")))
						{
							int index, count;
							Trade_StockHistItem stockItem;
							SoapObject singleHistory;
							String stockCode;
							String engName;
							String chnName;
							String orderPrice;
							String quantity, outQuantity, fillQuantity, cancelQuantity;
							String orderNum, orderType, orderSide;
							String timeStamp;
							String orderStatus;
							String orderStatusName;
							String prevClosePrice;
							String channel, details;
							String currency;
						
							count = tradeGroup.getPropertyCount();
							if (count != 0)
								stockList = new ArrayList<Trade_StockHistItem>();
	
							for (index = 0; index < count; index++)
							{
								// Get the index attribute
								singleHistory = (SoapObject) tradeGroup
										.getProperty(index);
	
								orderNum = TradeAppInfo.GetSoapProperty(
										singleHistory, LOG_TAG, "OrderNo");
								stockCode = TradeAppInfo.GetSoapProperty(
										singleHistory, LOG_TAG,
										"StockCode");
								timeStamp = TradeAppInfo.GetSoapProperty(
										singleHistory, LOG_TAG,
										"TimeStamp");
								orderPrice = TradeAppInfo.GetSoapProperty(
										singleHistory, LOG_TAG, "Price");
								quantity = TradeAppInfo.GetSoapProperty(
										singleHistory, LOG_TAG, "Qty");
								orderType = TradeAppInfo.GetSoapProperty(
										singleHistory, LOG_TAG,
										"OrderType");
								orderSide = TradeAppInfo.GetSoapProperty(
										singleHistory, LOG_TAG,
										"OrderSide");
								outQuantity = TradeAppInfo.GetSoapProperty(
										singleHistory, LOG_TAG, "OSQty");
								fillQuantity = TradeAppInfo.GetSoapProperty(
										singleHistory, LOG_TAG,
										"FilledQty");
								cancelQuantity = TradeAppInfo
										.GetSoapProperty(singleHistory,
												LOG_TAG, "CancelledQty");
								orderStatus = TradeAppInfo.GetSoapProperty(
										singleHistory, LOG_TAG,
										"StatusCode");
								orderStatusName = TradeAppInfo
										.GetSoapProperty(singleHistory,
												LOG_TAG, "StatusName");
								engName = TradeAppInfo.GetSoapProperty(
										singleHistory, LOG_TAG, "EngName");
								chnName = TradeAppInfo.GetSoapProperty(
										singleHistory, LOG_TAG,
										"ChineseName");
								prevClosePrice = TradeAppInfo
										.GetSoapProperty(singleHistory,
												LOG_TAG, "Prevclose");
								channel = TradeAppInfo.GetSoapProperty(
										singleHistory, LOG_TAG, "Channel");
								currency = TradeAppInfo.GetSoapProperty(
										singleHistory, LOG_TAG, "Cur");							
								details = TradeAppInfo.GetSoapProperty(
										singleHistory, LOG_TAG, "Detail");
	
								stockItem = new Trade_StockHistItem(
										stockCode, chnName, engName,
										prevClosePrice, currency);
								stockItem.SetReqOrderInfo(orderNum,
										orderPrice, orderType, orderSide,
										quantity, channel, timeStamp);
								stockItem.SetProcessOrderInfo(orderStatus,
										orderStatusName, fillQuantity,
										cancelQuantity, outQuantity);
								if ((details != null) && (!details.equals("")))
									stockItem.AppendProcessDetail(details);
	
								stockList.add(stockItem);
							}
						}
					}
					catch (Exception ie)
					{
						// More likely it does not include
						ie.printStackTrace();
						TDStockLog.e(LOG_TAG, "GetInfo: " + ie.toString());
					}
				}
			}
			catch (java.net.SocketTimeoutException e)
			{
				e.printStackTrace();
				TDStockLog.e(LOG_TAG, "Timeout: " + e.toString());
				resultCode = new TradeGetMultipleOrderResult(false, null, null,
						null);
				return resultCode;
			}
			catch (Exception e)
			{
				e.printStackTrace();
				TDStockLog.e(LOG_TAG, e.toString());
				resultCode = new TradeGetMultipleOrderResult(false, null, null,
						null);
				return resultCode;			
			}
	
			portRecord = new Trade_StockHistRecord();
			portRecord.SetStockHistoryAccountCode(accountCode);
			portRecord.SetStockHistoryRecordList(stockList);
	
			resultCode = new TradeGetMultipleOrderResult(hasSent, statusCode,
					brokerMessage, portRecord);
	
			return resultCode;
		}
	}
}
